const express = require('express');
const fs = require('fs');
//const WechatPay = require('wechatpay-nodejs-sdk');
const WechatPay = require('../wechatpay-nodejs-sdk');
const router = express.Router();
const Order = require('../models/Order');
const Product = require('../models/Product');
const logger = require('../logger');
const { ORDER_STATUS } = require('../constants');
const { WECHAT_APP_ID, WECHAT_MCH_ID, SECRET_KEY, WECHAT_NOTIFY_URL } = require('../config');
const wechatPay = new WechatPay({
    appid: WECHAT_APP_ID,//服务器ID
    mchid: WECHAT_MCH_ID,//商务ID
    secretKey: SECRET_KEY,//V3密钥
    publicKey: fs.readFileSync('./apiclient_cert.pem'),//商户的公钥
    privateKey: fs.readFileSync('./apiclient_key.pem')//商户的私钥
})
async function createOrder(productId) {
    //1.检查订单的ID是否正确 
    const product = await Product.findById(productId)
    if (!product) {
        throw new Error('产品未找到');
    }
    const newOrder = new Order({
        product: productId,
        totalFee: product.price,
        orderStatus: ORDER_STATUS.UN_PAID
    });
    await newOrder.save();
    return { product, newOrder }
}
async function invokeWechatPay(order, product, req) {
    const result = await wechatPay.transactions_native({
        description: `购买${product.name}`,//交易的描述
        out_trade_no: order.id,//商户的订单号
        notify_url: WECHAT_NOTIFY_URL,
        amount: {//订单金额
            total: product.price,//总金额
            currency: 'CNY'
        },
        scene_info: {//场景信息
            payer_client_ip: req.ip//用户终端IP
        }
    });
    logger.info(`transactions_native.result:${JSON.stringify(result)}`);
    const { code_url } = result;
    //更新订单信息,把支付二维码地址保存到订单里
    await Order.findByIdAndUpdate(order.id, { code_url });
    return code_url;
}
router.get(`/native/:productId`, async function (req, res) {
    try {
        //1.生成订单 
        const { productId } = req.params;
        const { product, newOrder } = await createOrder(productId);
        //2.调用统一下单接口API 
        const code_url = await invokeWechatPay(newOrder, product, req);
        //3.把新生成的订单号和支付二维码地址发回给客户端
        res.send({ orderNo: newOrder.id, code_url })
    } catch (error) {
        logger.error(`Native Pay Error`, error);
        res.status(500).send(error.message);
    }
});
/**
 * 接收微信服务器发给商户后台的支付成功的通知
 */
router.post('/callback', async (req, res) => {
    try {
        //验证签名 保证此通知是真的是由微信服务器发过来的
        const { headers, body } = req;
        //Wechatpay-Signature 签名
        const signature = headers['wechatpay-signature'];
        logger.info('signature', signature)
        //Wechatpay-Serial 微信服务器平台的证书序列号
        const serial = headers['wechatpay-serial'];
        logger.info('serial', serial)
        //HTTP 头 Wechatpay-Timestamp 中的应答时间戳
        const timestamp = headers['wechatpay-timestamp'];
        logger.info('timestamp', timestamp)
        //HTTP 头 Wechatpay-Nonce 中的应答随机串
        const nonce = headers['wechatpay-nonce'];
        logger.info('nonce', nonce)
        const isVerified = await wechatPay.verifySign({
            body,//请求主体
            signature,//微信服务器发过来的签名
            serial,//证书序列号
            nonce,//随机字符串
            timestamp//时间戳
        });
        logger.info('isVerified', isVerified)
        logger.info('body', body);
        //如果事件类型是TRANSACTION.SUCCESS说明交易成功，说明用户支付成功
        if (isVerified && body && body.event_type === 'TRANSACTION.SUCCESS') {
            const resultStr = wechatPay.decrypt(body.resource);
            const result = JSON.parse(resultStr);
            logger.info('TRANSACTION.SUCCESS', result);
            //更新订单的状态为支付成功
            await Order.findByIdAndUpdate(result.out_trade_no, {
                orderStatus: ORDER_STATUS.PAID
            });
            res.status(200).send({
                code: 'SUCCESS',
                message: '支付成功'
            });
        } else {
            res.status(200).send({
                code: 'FAIL',
                message: '支付失败'
            });
        }

    } catch (error) {
        logger.error('接收通知失败', error)
        res.status(500).send(`处理微信支付服务器回调失败` + error.message);
    }
});
router.get('/order/:orderNo', async (req, res) => {
    try {
        const {orderNo }= req.params;
        const result = await wechatPay.query(orderNo);
        logger.info('query order',result);
        res.status(200).send(result);
    } catch (error) {
        logger.error('查询交易状态失败', error)
        res.status(500).send(`查询交易状态失败` + error.message);
    }
})
router.get('/order/:orderNo/close', async (req, res) => {
    try {
        const {orderNo }= req.params;
        await wechatPay.close(orderNo);
        await Order.findByIdAndUpdate(orderNo, { orderStatus:ORDER_STATUS.CLOSE });
        res.status(200).send({message:'关闭订单成功'});
    } catch (error) {
        logger.error('关闭订单失败', error)
        res.status(500).send(`关闭订单失败` + error.message);
    }
})
module.exports = router;